#include "sessionfriendarea.h"
#include "debug.h"
#include "model/data.h"

#include <QScrollBar>
#include <QVBoxLayout>
#include <QStyleOption>
#include <QPainter>

///
/// \brief SessionFriendArea::SessionFriendArea 构造一个列表区域
/// \param parent 列表区域控件的父级控件指针
///
SessionFriendArea::SessionFriendArea(QWidget *parent)
    : QScrollArea(parent)
{
    QString vScrollBarStyle = "QScrollBar:vertical { width : 5px; background : none; border : none; margin : 0 px; }";
    vScrollBarStyle += "QScrollBar::handle:vertical { background: #c0c0c0; min-height: 20px; border-radius: 5px; }";
    vScrollBarStyle += "QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0px; }";
    vScrollBarStyle += "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { background: rgb(240, 240, 240); }";

    QVBoxLayout *layout = new QVBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setAlignment(Qt::AlignTop);

    container = new QWidget();
    container->setFixedWidth(310);
    container->setLayout(layout);

    this->setWidget(container);
    this->setWidgetResizable(true);     // 开启滚动效果
    this->verticalScrollBar()->setStyleSheet(vScrollBarStyle);
    this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height : 0px; }");

#if TEST_UI
#if TEST_UI_SESSIONFRIENDITEM
    // // 测试的代码1：添加按钮测试滚动条效果
    // for (int i = 0; i < 100; i++) {
    //     layout->addWidget(new QPushButton());
    // }

    // 测试代码2：构建临时Item测试UI效果
    for (int i = 0; i < 11; i++) {
        QIcon avatar(":/resource/image/defaultAvatar.png");
        QString name = "张三" + QString::number(i);
        QString text = "最后一条消息" + QString::number(i);
        this->addItem(SESSIONITEMTYPE, QString::number(i), avatar, name, text);
    }
#endif
#endif
}

///
/// \brief SessionFriendArea::clear 清空列表区域的所有Item
///
void SessionFriendArea::clear()
{
    QLayout *layout = container->layout();
    for (int i = layout->count(); i >= 0; i--) {
        QLayoutItem *layoutItem = layout->takeAt(i);
        QWidget *window = layoutItem->widget();
        if (nullptr != window) {
            delete window; // 自动管理自动释放，手动管理手动释放
        }
    }
}

///
/// \brief SessionFriendArea::addItem 向列表区域添加Item
/// \param itemType Item的类型
/// \param id 会话标示，如果是SessionItem就是chatSessionId；如果是FriendItem/ApplyItem就是userId
/// \param avatar Item的头像
/// \param name Item的名称
/// \param text Item的文本(消息预览/个性签名)
///
void SessionFriendArea::addItem(ItemType itemType, const QString &id, const QIcon &avatar, const QString &name, const QString &text)
{
    SessionFriendItem *item = nullptr;
    switch(itemType) {
    case SESSIONITEMTYPE:
        item = new SessionItem(this, id, avatar, name, text);
        break;
    case FRIENDITEMTYPE:
        item = new FriendItem(this, id, avatar, name, text);
        break;
    case APPLYITEMTYPE:
        item = new ApplyItem(this, id, avatar, name);
        break;
    default:
        LOG() << "错误的ItemType！ItemType=" << itemType;
        return ;
    }
    container->layout()->addWidget(item);
}

///
/// \brief SessionFriendArea::addItem 向列表区域添加Item
/// \param avatar Item的头像
/// \param name Item的名称
/// \param text Item的文本(消息预览/个性签名)
///
void SessionFriendArea::addItem(const QIcon &avatar, const QString &name, const QString &text)
{
    SessionFriendItem *item = new SessionFriendItem(this, avatar, name, text);
    container->layout()->addWidget(item);
}

///
/// \brief SessionFriendArea::clickItem 通过指定索引选中Item
/// \param index Item的索引值
///
void SessionFriendArea::clickItem(int index)
{
    QLayout *layout = container->layout();
    if (index < 0 || index >= layout->count()) {
        LOG() << "用户点击元素超出下标范围！index=" << index;
        return ;
    }

    QLayoutItem* layoutItem = layout->itemAt(index);
    if (nullptr == layoutItem || nullptr == layoutItem->widget()) {
        LOG() << "用户点击元素不存在！";
        return ;
    }

    SessionFriendItem *item = dynamic_cast<SessionFriendItem *>(layoutItem->widget());
    item->select();
}

///
/// \brief SessionFriendItem::SessionFriendItem 实例化一个列表项
/// \param owner 指向当前Item所属的Area实例的指针
/// \param avatar 当前Item的头像
/// \param name 当前Item的名字
/// \param text 当前Item所包含的文本信息(消息的预览/个性签名)
///
SessionFriendItem::SessionFriendItem(QWidget *owner, const QIcon &avatar, const QString &name, const QString &text)
    : owner(owner)
{
    QPushButton *userAvatarBtn = new QPushButton();
    userAvatarBtn->setFixedSize(QSize(50, 50));
    userAvatarBtn->setIconSize(QSize(50, 50));
    userAvatarBtn->setIcon(avatar);
    userAvatarBtn->setFlat(true);
    QString userAvatarBtnStyle = "QPushButton { border : none }";
    userAvatarBtn->setStyleSheet(userAvatarBtnStyle);
    userAvatarBtn->setFocusPolicy(Qt::ClickFocus);
    userAvatarBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // 头像固定大小不随着窗体拉伸而变化

    QLabel *nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel { font-size : 16px; font-weight : 600 }");
    nameLabel->setFixedHeight(35);
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // 宽度根据父窗口拉伸适应，高度固定

    messageLabel = new QLabel();
    messageLabel->setText(text);
    messageLabel->setFixedHeight(35);
    messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // 宽度根据父窗口拉伸适应，高度固定

    QGridLayout *layout = new QGridLayout();
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(0);
    layout->setContentsMargins(10, 0, 0, 0); // 左边10px是为了图片不紧挨着边界，右边3px是留给滚动条的
    layout->addWidget(userAvatarBtn, 0, 0, 2, 2);
    layout->addWidget(nameLabel, 0, 2, 1, 8);
    layout->addWidget(messageLabel, 1, 2, 1, 8);

    this->setLayout(layout);
    this->setFixedHeight(70);
    this->setStyleSheet("QWidget { background-color : rgb(240, 240, 240); }");
}

///
/// \brief SessionFriendItem::paintEvent 重写绘画事件，让自定义控件支持样式设置
/// \param event 事件
///
void SessionFriendItem::paintEvent(QPaintEvent *event)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

///
/// \brief SessionFriendItem::mousePressEvent 鼠标点击Item事件的处理方法
/// \param event 事件发起者
///
void SessionFriendItem::mousePressEvent(QMouseEvent *event)
{
    (void)event;
    select();
}

///
/// \brief SessionFriendItem::enterEvent 鼠标悬停Item事件的处理方法
/// \param event 事件发起者
///
void SessionFriendItem::enterEvent(QEnterEvent *event)
{
    (void)event;
    if (false == this->selected) {
        this->setStyleSheet("QWidget { background-color : rgb(215, 215, 215); }");
    }
}

///
/// \brief SessionFriendItem::leaveEvent 鼠标离开Item事件的处理方法
/// \param event 事件发起者
///
void SessionFriendItem::leaveEvent(QEvent *event)
{
    (void)event;
    if (false == this->selected) {
        this->setStyleSheet("QWidget { background-color : rgb(240, 240, 240); }");
    }
}

///
/// \brief SessionFriendItem::select 选中Item时进行Item的颜色切换
///
void SessionFriendItem::select()
{
    // 先清除之前选中Item样式
    const QObjectList children = this->parentWidget()->children();
    for (QObject *child : children) {
        if (false == child->isWidgetType()) {
            continue;
        }
        SessionFriendItem *item = dynamic_cast<SessionFriendItem *>(child);
        if (true == item->selected) {
            item->selected = false;
            item->setStyleSheet("QWidget { background-color : rgb(240, 240, 240); }");
        }
    }

    // 再设置当前选中Item样式
    this->setStyleSheet("QWidget { background-color : rgb(210, 210, 210); }");
    this->selected = true;

    // 该方法中封装了期望Item被点击后的业务逻辑
    this->active();
}

///
/// \brief SessionFriendItem::active 封装了期望Item被点击后的业务逻辑
/// \remark 该方法主要提供于子类重写
///
void SessionFriendItem::active()
{
    // TODO???
}

///
/// \brief SessionItem::SessionItem 构造会话列表项
/// \param owner
/// \param chatSessionId
/// \param avatar
/// \param name
/// \param lastMessage
///
SessionItem::SessionItem(QWidget *owner, const QString &chatSessionId, const QIcon &avatar, const QString &name, const QString &lastMessage)
    : SessionFriendItem(owner, avatar, name, lastMessage)
    , chatSessionId(chatSessionId)
{
    // TODO???
}

void SessionItem::active()
{
#if TEST_UI
#if TEST_UI_SESSIONITEM_ACTIVE
    LOG() << "点击SessionItem触发的逻辑！chatSessionId=" << chatSessionId;
#endif
#endif
    // TODO???
}

///
/// \brief FriendItem::FriendItem  构造好友列表项
/// \param owner
/// \param userId
/// \param avatar
/// \param name
/// \param description
///
FriendItem::FriendItem(QWidget *owner, const QString &userId, const QIcon &avatar, const QString &name, const QString &description)
    : SessionFriendItem(owner, avatar, name, description)
    , userId(userId)
{
    // TODO???
}

void FriendItem::active()
{
#if TEST_UI
#if TEST_UI_SESSIONITEM_ACTIVE
    LOG() << "点击FriendItem触发的逻辑！userId=" << userId;
#endif
#endif
    // TODO???
}

///
/// \brief ApplyItem::ApplyItem 构造好友申请列表项
/// \param owner
/// \param userId
/// \param avatar
/// \param name
///
ApplyItem::ApplyItem(QWidget *owner, const QString &userId, const QIcon &avatar, const QString &name)
    : SessionFriendItem(owner, avatar, name, "")
    , userId(userId)
{
    // 1. 移除父类的messageLabel
    QGridLayout *layout = dynamic_cast<QGridLayout *>(this->layout());
    layout->removeWidget(messageLabel);
    delete messageLabel; // 谨记避免内存泄露

    // 2. 实例化同意、拒绝按钮并设置样式
    acceptBtn = new QPushButton();
    acceptBtn->setText("同意");
    acceptBtn->setFocusPolicy(Qt::ClickFocus);
    QString acceptBtnStyle = "QPushButton { background-color: #4CAF50; border : none; border-radius : 5px; }";
    acceptBtnStyle += "QPushButton:hover { background-color: #43A047; }";
    acceptBtnStyle += "QPushButton:pressed { background-color: #388E3C; }";
    acceptBtn->setStyleSheet(acceptBtnStyle);

    rejectBtn = new QPushButton();
    rejectBtn->setText("拒绝");
    rejectBtn->setFocusPolicy(Qt::ClickFocus);
    QString rejectBtnBtnStyle = "QPushButton { background-color: #F44336; border : none; border-radius : 5px; }";
    rejectBtnBtnStyle += "QPushButton:hover { background-color: #E53935; }";
    rejectBtnBtnStyle += "QPushButton:pressed { background-color: #D32F2F; }";
    rejectBtn->setStyleSheet(rejectBtnBtnStyle);

    // 3. 将按钮加入好友申请列表项的布局管理器
    layout->addWidget(acceptBtn, 1, 2, 1, 3);
    layout->addWidget(rejectBtn, 1, 5, 1, 3);

    // 4. 添加信号槽
    connect(acceptBtn, &QPushButton::clicked, this, &ApplyItem::acceptFriendApply);
    connect(rejectBtn, &QPushButton::clicked, this, &ApplyItem::rejectFriendApply);
}

void ApplyItem::paintEvent(QPaintEvent *event)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void ApplyItem::active()
{
#if TEST_UI
#if TEST_UI_SESSIONITEM_ACTIVE
    LOG() << "点击ApplyItem触发的逻辑！userId=" << userId;
#endif
#endif
    // TODO???
}

void ApplyItem::acceptFriendApply()
{
    // TODO???
}

void ApplyItem::rejectFriendApply()
{
    // TODO???
}
